package org.jeecg.modules.demo.yyc;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 类说明
 *
 * @ClassName DownGoogleTile
 * @Description TODO
 * @Author think
 * @Date 2024/2/25 16:57
 **/
public class DownGoogleTile {

    public static void main(String[] args) {
        double minLatitude = 40.7128; // 最小纬度
        double maxLatitude = 40.7749; // 最大纬度
        double minLongitude = -74.0060; // 最小经度
        double maxLongitude = -73.9683; // 最大经度
        int zoomLevel = 2; // 缩放级别
        String outputPath = "E:\\workspace\\btcode.weather.zkfish\\frontend\\public\\googletile\\"; // 指定的输出路径

        String tileServerUrl = "https://khms2.google.com/kh/v=969?{z}/{x}/{y}.png"; // 瓦片服务器URL模板

        int[] tileRange = getTileRange(minLatitude, maxLatitude, minLongitude, maxLongitude, zoomLevel);

        for (int x = tileRange[0]; x <= tileRange[2]; x++) {
            for (int y = tileRange[1]; y <= tileRange[3]; y++) {
                String tileUrl = tileServerUrl
                        .replace("{z}", String.valueOf(zoomLevel))
                        .replace("{x}", String.valueOf(x))
                        .replace("{y}", String.valueOf(y));

                String fileName = "tile_" + zoomLevel + "_" + x + "_" + y + ".png";
                String filePath = outputPath + fileName;

                try {
                    downloadTile(tileUrl, filePath);
                    System.out.println("Downloaded tile: " + fileName);
                } catch (IOException e) {
                    System.err.println("Failed to download tile: " + fileName);
                    e.printStackTrace();
                }
            }
        }
    }

    private static void downloadTile(String url, String filePath) throws IOException {
        URL tileUrl = new URL(url);
        HttpURLConnection connection = (HttpURLConnection) tileUrl.openConnection();
        connection.setRequestMethod("GET");

        InputStream inputStream = connection.getInputStream();
        FileOutputStream outputStream = new FileOutputStream(filePath);

        byte[] buffer = new byte[4096];
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }

        outputStream.close();
        inputStream.close();
        connection.disconnect();
    }

    private static int[] getTileRange(double minLat, double maxLat, double minLon, double maxLon, int zoomLevel) {
        int[] tileRange = new int[4];

        double minLatRad = Math.toRadians(minLat);
        double maxLatRad = Math.toRadians(maxLat);
        double minLonRad = Math.toRadians(minLon);
        double maxLonRad = Math.toRadians(maxLon);

        int tileSize = 256;
        double initialResolution = 2 * Math.PI * 6378137 / tileSize;
        double originShift = 2 * Math.PI * 6378137 / 2.0;

        double minTileX = (minLonRad + originShift) / initialResolution;
        double maxTileX = (maxLonRad + originShift) / initialResolution;
        double minTileY = (originShift - Math.log(Math.tan(minLatRad) + 1 / Math.cos(minLatRad)) / initialResolution);
        double maxTileY = (originShift - Math.log(Math.tan(maxLatRad) + 1 / Math.cos(maxLatRad)) / initialResolution);

        tileRange[0] = (int) Math.floor(minTileX);
        tileRange[1] = (int) Math.floor(minTileY);
        tileRange[2] = (int) Math.floor(maxTileX);
        tileRange[3] = (int) Math.floor(maxTileY);

        return tileRange;
    }
}
